/**
 * @file lockfree_queue.h
 * @brief 高性能无锁队列实现
 * 
 * 这个无锁队列实现针对高频交易系统的特殊需求进行了优化：
 * 1. 单生产者单消费者(SPSC)设计，适合特定的数据流模式
 * 2. 完全无锁实现，避免互斥锁的性能开销
 * 3. 缓存行对齐，减少false sharing
 * 4. 预分配内存，避免运行时内存分配
 */

#pragma once

#include <array>
#include <atomic>
#include <cstddef>
#include <optional>
#include <type_traits>

namespace hft {
namespace utils {

/**
 * @brief 单生产者单消费者(SPSC)无锁队列
 * 
 * @tparam T 队列中元素的类型
 * @tparam N 队列的容量，必须是2的幂
 */
template<typename T, size_t N>
class LockfreeQueue {
    static_assert((N > 0) && ((N & (N - 1)) == 0), 
                  "Queue size must be a power of 2");
    static_assert(std::is_nothrow_copy_assignable<T>::value || 
                  std::is_nothrow_move_assignable<T>::value,
                  "Type must be nothrow copy or move assignable");

public:
    /**
     * @brief 构造函数
     */
    LockfreeQueue() noexcept : head_(0), tail_(0) {}

    /**
     * @brief 尝试将元素推入队列
     * 
     * @param item 要推入的元素
     * @return bool 如果成功推入返回true，队列已满返回false
     */
    template<typename U>
    bool try_push(U&& item) noexcept {
        const size_t current_tail = tail_.load(std::memory_order_relaxed);
        const size_t next_tail = (current_tail + 1) & mask_;
        
        if (next_tail == head_.load(std::memory_order_acquire)) {
            return false;  // 队列已满
        }
        
        if constexpr (std::is_nothrow_move_assignable<T>::value) {
            buffer_[current_tail] = std::move(item);
        } else {
            buffer_[current_tail] = item;
        }
        
        tail_.store(next_tail, std::memory_order_release);
        return true;
    }

    /**
     * @brief 尝试从队列中弹出元素
     * 
     * @param item 用于存储弹出元素的引用
     * @return bool 如果成功弹出返回true，队列为空返回false
     */
    bool try_pop(T& item) noexcept {
        const size_t current_head = head_.load(std::memory_order_relaxed);
        
        if (current_head == tail_.load(std::memory_order_acquire)) {
            return false;  // 队列为空
        }
        
        item = std::move(buffer_[current_head]);
        head_.store((current_head + 1) & mask_, std::memory_order_release);
        return true;
    }

    /**
     * @brief 尝试从队列中弹出元素
     * 
     * @return std::optional<T> 如果队列不为空，返回队首元素；否则返回空
     */
    std::optional<T> try_pop() noexcept {
        const size_t current_head = head_.load(std::memory_order_relaxed);
        
        if (current_head == tail_.load(std::memory_order_acquire)) {
            return std::nullopt;  // 队列为空
        }
        
        T item = std::move(buffer_[current_head]);
        head_.store((current_head + 1) & mask_, std::memory_order_release);
        return item;
    }

    /**
     * @brief 检查队列是否为空
     * 
     * @return bool 如果队列为空返回true，否则返回false
     */
    bool empty() const noexcept {
        return head_.load(std::memory_order_acquire) == 
               tail_.load(std::memory_order_acquire);
    }

    /**
     * @brief 检查队列是否已满
     * 
     * @return bool 如果队列已满返回true，否则返回false
     */
    bool full() const noexcept {
        const size_t next_tail = (tail_.load(std::memory_order_acquire) + 1) & mask_;
        return next_tail == head_.load(std::memory_order_acquire);
    }

    /**
     * @brief 获取队列中当前元素数量
     * 
     * @return size_t 队列中的元素数量
     */
    size_t size() const noexcept {
        const size_t head = head_.load(std::memory_order_acquire);
        const size_t tail = tail_.load(std::memory_order_acquire);
        return (tail - head) & mask_;
    }

    /**
     * @brief 获取队列的容量
     * 
     * @return constexpr size_t 队列的容量
     */
    constexpr size_t capacity() const noexcept {
        return N - 1;  // 实际可用容量比N小1，因为需要一个空位来区分空和满
    }

    /**
     * @brief 清空队列
     */
    void clear() noexcept {
        head_.store(0, std::memory_order_relaxed);
        tail_.store(0, std::memory_order_relaxed);
    }

private:
    // 用于快速计算索引的掩码
    static constexpr size_t mask_ = N - 1;
    
    // 缓存行对齐的头指针（消费者使用）
    alignas(64) std::atomic<size_t> head_;
    
    // 缓存行对齐的尾指针（生产者使用）
    alignas(64) std::atomic<size_t> tail_;
    
    // 数据存储
    alignas(64) std::array<T, N> buffer_;
};

} // namespace utils
} // namespace hft